package com.star.rpc.server.tcp;

import com.star.rpc.modal.RpcRequest;
import com.star.rpc.modal.RpcResponse;
import com.star.rpc.protocol.*;
import com.star.rpc.registry.LocalRegistry;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * packageName com.star.rpc.server.tcp
 *
 * @author zerostart
 * @className TcpServerHandler
 * @date 2024/12/4
 * @description
 */
@Slf4j
public class TcpServerHandler implements Handler<NetSocket> {


    /**
     * 处理请求
     *
     * @param socket the event to handle
     */
    @Override
    public void handle(NetSocket socket) {
        log.info("收到客户端连接: {}", socket.remoteAddress());
        TcpBufferHandlerWrapper bufferHandlerWrapper = new TcpBufferHandlerWrapper(buffer -> {
            // 接受请求，解码
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (Exception e) {
                throw new RuntimeException("协议消息解码错误");
            }
            RpcRequest rpcRequest = protocolMessage.getBody();
            ProtocolMessage.Header header = protocolMessage.getHeader();

            // 处理请求
            // 构造响应结果对象
            RpcResponse rpcResponse = new RpcResponse();
            try {
                // 获取要调用的服务实现类，通过反射调用
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                //
                System.out.println("本地注册中心："+ LocalRegistry.get(rpcRequest.getServiceName()));
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                // 封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
                log.info("服务端处理请求，返回响应{}",rpcResponse);
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }

            // 发送响应，编码
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
            header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());
            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, rpcResponse);
            try {
                Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
                socket.write(encode);
                log.info("服务端发送响应，返回响应{}",rpcResponse);
            } catch (Exception e) {
                throw new RuntimeException("协议消息编码错误");
            }
        });
        socket.handler(bufferHandlerWrapper);
//        socket.handler(buffer -> {
//            // 接受请求，解码
//            ProtocolMessage<RpcRequest> protocolMessage;
//            try {
//                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
//            } catch (Exception e) {
//                throw new RuntimeException("协议消息解码错误");
//            }
//            RpcRequest rpcRequest = protocolMessage.getBody();
//            ProtocolMessage.Header header = protocolMessage.getHeader();
//
//            // 处理请求
//            // 构造响应结果对象
//            RpcResponse rpcResponse = new RpcResponse();
//            try {
//                // 获取要调用的服务实现类，通过反射调用
//                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
//                //
//                System.out.println("本地注册中心："+ LocalRegistry.get(rpcRequest.getServiceName()));
//                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
//                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
//                // 封装返回结果
//                rpcResponse.setData(result);
//                rpcResponse.setDataType(method.getReturnType());
//                rpcResponse.setMessage("ok");
//                log.info("服务端处理请求，返回响应{}",rpcResponse);
//            } catch (Exception e) {
//                e.printStackTrace();
//                rpcResponse.setMessage(e.getMessage());
//                rpcResponse.setException(e);
//            }
//
//            // 发送响应，编码
//            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
//            header.setStatus((byte) ProtocolMessageStatusEnum.OK.getValue());
//            ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, rpcResponse);
//            try {
//                Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
//                socket.write(encode);
//                log.info("服务端发送响应，返回响应{}",rpcResponse);
//            } catch (Exception e) {
//                throw new RuntimeException("协议消息编码错误");
//            }
//        });
    }

    public void handle1(NetSocket netSocket) {
        //处理连接
        netSocket.handler(buffer -> {

            System.out.println("收到请求");
            // 接受请求，解码
            ProtocolMessage<RpcRequest> protocolMessage;

            try {
                protocolMessage = (ProtocolMessage<RpcRequest>)ProtocolMessageDecoder.decode(buffer);
            } catch (Exception e) {
                throw new RuntimeException("协议解码错误");
            }
            RpcRequest rpcRequest = protocolMessage.getBody();

            System.out.println("收到请求：" + rpcRequest);


            RpcResponse rpcResponse = new RpcResponse();
            //处理请求
            // 构造响应结果
            try {
                // 获取调用的服务实现类，通过反射调用
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                // 封装返回结果
                rpcResponse.setData(result);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setMessage("ok");
            }

            //发送响应， 编码
            ProtocolMessage.Header header = new ProtocolMessage.Header();
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
            ProtocolMessage<RpcResponse> rpcResponseProtocolMessage = new ProtocolMessage<>(header, rpcResponse);

            try {
                Buffer encode = ProtocolMessageEncoder.encode(rpcResponseProtocolMessage);
                netSocket.write(encode);
            } catch (Exception e) {
                throw new RuntimeException("协议编码错误");
            }

        });
    }
}
